﻿using SmartHRMS.Model.Account;
using SmartHRMS.Infrastructure;
using System.Web;
using System.Collections;
using System.Security.Principal;
using System.Web.Security;
using SmartHRMS.Infrastructure.Caching;

namespace SmartHRMS.Services
{
    public class PrincipalService :CachableApi, IPrincipalService
    {
        internal const string CurrentUserSessionKey = "CurrentUser";
        private IPrincipalRepository _CustomPrincipalRepository;
        private IUnitOfWork _UnitOfWork;

        public PrincipalService(IPrincipalRepository customPrincipalRepository, IUnitOfWork unitOfWork)
        {
            this._CustomPrincipalRepository = customPrincipalRepository;
            this._CustomPrincipalRepository.Inject(unitOfWork);
            this._UnitOfWork = unitOfWork;
        }



        #region ICustomPrincipalService Members

        public User User
        {
            get
            {
                User userObject = this.Session[CurrentUserSessionKey] as User;

                if (userObject != null)
                {
                    this.Session[CurrentUserSessionKey] = null;
                    userObject = null;
                }

                if (userObject == null || userObject.UserName != HttpContext.Current.User.Identity.Name)
                {
                    userObject = _CustomPrincipalRepository.LoadUserByUserName(this.Identity.Name);
                    this.Session[CurrentUserSessionKey] = userObject;
                }

                return userObject;
            }
        }

        public void Logout()
        {
            if (this.User == null) return;
            base.RemoveCache(User.UserId);
           // _CustomPrincipalRepository.Logout(this.User.UserId);
        }

        public void Act()
        {
            throw new System.NotImplementedException();
        }

        public User LoadUserById(System.Guid userId)
        {
            throw new System.NotImplementedException();
        }

        public User LoadUserByUserName(string userName)
        {
           return _CustomPrincipalRepository.LoadUserByUserName(userName);
        }

        public LoginResults Login(string userName, string password)
        {
            LoginResults result=_CustomPrincipalRepository.Login(userName, Kit.EncryptPassword(password));
            if(result!=LoginResults.Successful)
                return result;

            this.Session[CurrentUserSessionKey] = _CustomPrincipalRepository.LoadUserByUserName(userName);
			HttpContext.Current.User = new GenericPrincipal(new GenericIdentity(userName), new string[0]);
			FormsAuthentication.SetAuthCookie(userName, true);
			return LoginResults.Successful;

        }

        #endregion

        #region IApplicationContext Members

        public System.Collections.IDictionary Session
        {
            get
            {
                const string contextKey = "SmartHRMS.Services.CustomPrincipalService::Session";
                if (HttpContext.Current.Session[contextKey] == null)
                    HttpContext.Current.Session.Add(contextKey, new Hashtable());

                return HttpContext.Current.Session[contextKey] as Hashtable;
            }
        }

        public System.Collections.IDictionary TempVariables
        {
            get
            {
                const string contextKey = "SmartHRMS.Services.CustomPrincipalService::TempVariables";
                if (!HttpContext.Current.Items.Contains(contextKey))
                    HttpContext.Current.Items.Add(contextKey, new Hashtable());

                return HttpContext.Current.Items[contextKey] as Hashtable;
            }
        }

        public System.Security.Principal.IIdentity Identity
        {
            get
            {
                if (HttpContext.Current.User == null || HttpContext.Current.User.Identity == null || !HttpContext.Current.User.Identity.IsAuthenticated)
                    HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new AnonymousIdentity(PermissionConst.ANONYMOUS), new string[] { });

                return HttpContext.Current.User.Identity;
            }
        }

        public string ClientIPAddress
        {
            get { return HttpContext.Current.Request.UserHostAddress; }
        }

        #endregion
    }
}
